package com.brillilab.service.core.lab.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.brillilab.common.entity.PageVo;
import com.brillilab.common.utils.MyBeanUtils;
import com.brillilab.dao.mapper.lab.LabMapper;
import com.brillilab.dao.mapper.lab.LabMemberMapper;
import com.brillilab.domain.enums.common.BoolEnum;
import com.brillilab.domain.enums.lab.LabMemberEnum;
import com.brillilab.domain.po.lab.Lab;
import com.brillilab.domain.po.lab.LabMember;
import com.brillilab.domain.po.lab.LabMemberPower;
import com.brillilab.domain.po.lab.LabUserCard;
import com.brillilab.domain.vo.lab.LabMemberSelector;
import com.brillilab.domain.vo.lab.LabMemberVo;
import com.brillilab.domain.vo.lab.MemberInfoVo;
import com.brillilab.domain.vo.user.UsersVo;
import com.brillilab.service.core.lab.ILabMemberPowerService;
import com.brillilab.service.core.lab.ILabMemberService;
import com.brillilab.service.core.lab.ILabUserCardService;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class LabMemberServiceImpl implements ILabMemberService {

    @Resource
    private LabMapper labMapper;
    @Resource
    private LabMemberMapper labMemberMapper;
    @Resource
    private ILabUserCardService labUserCardService;
    @Resource
    private ILabMemberPowerService labMemberPowerService;

    @Override
    public boolean updateById(LabMember labMember) {
        int b=labMemberMapper.updateById(labMember);
        return b == 1 ? true : false;
    }

    @Override
    public boolean updateState(Long id,Integer state) {
        Assert.isTrue(LabMemberEnum.State.getKey(state) != null,"参数错误");
        LabMember labMember=labMemberMapper.selectById(id);
        labMember.setState(state);
        labMember.setUpdateTime(new Date());
        int b=labMemberMapper.updateById(labMember);
        return b == 1 ? true : false;
    }

    @Override
    public LabMember selectById(Long id) {
        LabMember labMember=labMemberMapper.selectById(id);
        if(labMember!=null){
            labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
        }
        return labMember;
    }


    @Override
    public PageVo<LabMemberVo> selectPage(Long labId,Integer state,int pageNum,int pageSize) {
        pageNum = pageNum > 0 ? pageNum : 1;
        pageSize = pageSize > 0 ? pageSize : 10;
        Integer startRow=pageSize * (pageNum - 1);
        List<LabMemberVo> labMemberVos = labMemberMapper.selectVoPage(labId,state,startRow,pageSize);
        List<Long> userIds=labMemberVos.stream().map(LabMemberVo::getUserId).distinct().collect(Collectors.toList());
        List<Long> labMemberIds=labMemberVos.stream().map(LabMemberVo::getLabMemberId).distinct().collect(Collectors.toList());
        List<LabUserCard> cards =labId!=null && userIds.size()>0 ? labUserCardService.selectListByLabIdInUserIds(labId,userIds):new ArrayList<>(0);
        List<LabMemberPower> powers = labId!=null && labMemberIds.size()>0 ? labMemberPowerService.selectListByLabIdInLabMemberIds(labId,labMemberIds):new ArrayList<>(0);

        labMemberVos.forEach(labMemberVo -> {
            LabUserCard myCard=cards.stream().filter(card -> card.getUserId().equals(labMemberVo.getUserId())).findFirst().orElse(null);
            labMemberVo.setBindCard(myCard!=null ? BoolEnum.TRUE.getValue() : BoolEnum.FALSE.getValue());
            List<LabMemberPower> myPower=powers.stream().filter(power -> power.getLabMemberId().equals(labMemberVo.getLabMemberId())).collect(Collectors.toList());
            if(labMemberVo.getIsOwner()){//实验室所有者重新复制前端显示
                List<LabMemberPower> powerList=new ArrayList<>();
                LabMemberPower power=new LabMemberPower();
                power.setPowerName("全部权限");
                powerList.add(power);
                labMemberVo.setPowerList(powerList);
            }else {
                labMemberVo.setPowerList(myPower);
            }
            labMemberVo.setDuty(labMemberVo.getDuty()!=null?labMemberVo.getDuty():"PI");
        });

        Integer totalRow=selectCount(labId,state);

        return new PageVo<>(pageNum,pageSize,totalRow,labMemberVos);
    }

    @Override
    public LabMember selectMember(Long labId,Long userId) {
        LambdaQueryWrapper<LabMember> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(LabMember::getLabId,labId);
        wrapper.eq(LabMember::getUserId,userId);
        wrapper.eq(LabMember::getState,LabMemberEnum.State.STATE_IN.getValue());
        LabMember labMember=labMemberMapper.selectOne(wrapper);
        if(labMember!=null){
            labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
        }
        return labMember;
    }

    @Override
    public LabMember add(LabMember labMember) {
        //判断是否已经存在
        LabMember member=selectMember(labMember.getLabId(),labMember.getUserId());
        if(member != null){//存在更新数据
            MyBeanUtils.copyPropertiesNotNull(labMember,member);
            member.setState(LabMemberEnum.State.STATE_IN.getValue());
            labMemberMapper.updateById(member);
        } else {//不存在添加数据
            labMember.setState(LabMemberEnum.State.STATE_IN.getValue());
            labMemberMapper.insert(labMember);
        }
        labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
        return labMember;
    }


    @Override
    public List<LabMemberVo> selectByLabId(Long labId) {

        return this.selectList(labId,LabMemberEnum.State.STATE_IN.getValue());
    }

    @Override
    public List<LabMemberVo> selectList(Long labId,Integer state) {
        Lab lab=labMapper.selectById(labId);
        Assert.notNull(lab,"实验室不存在！");
        List<LabMemberVo> labMemberVos = labMemberMapper.selectVoList(labId,state);
        List<Long> userIds=labMemberVos.stream().map(LabMemberVo::getUserId).distinct().collect(Collectors.toList());
        List<Long> labMemberIds=labMemberVos.stream().map(LabMemberVo::getLabMemberId).distinct().collect(Collectors.toList());
        List<LabUserCard> cards =labId!=null && userIds.size()>0 ? labUserCardService.selectListByLabIdInUserIds(labId,userIds):new ArrayList<>(0);
        List<LabMemberPower> powers = labId!=null && labMemberIds.size()>0 ? labMemberPowerService.selectListByLabIdInLabMemberIds(labId,labMemberIds):new ArrayList<>(0);

        labMemberVos.forEach(labMemberVo -> {
            LabUserCard myCard=cards.stream().filter(card -> card.getUserId().equals(labMemberVo.getUserId())).findFirst().orElse(null);
            labMemberVo.setBindCard(myCard!=null ? BoolEnum.TRUE.getValue() : BoolEnum.FALSE.getValue());
            List<LabMemberPower> myPower=powers.stream().filter(power -> power.getLabMemberId().equals(labMemberVo.getLabMemberId())).collect(Collectors.toList());
            labMemberVo.setPowerList(myPower);
            labMemberVo.setDuty(labMemberVo.getDuty()!=null?labMemberVo.getDuty():"PI");
        });

        LabMemberVo owner=labMemberVos.stream().filter(e -> e.getUserId().equals(lab.getOwnerId())).findFirst().orElse(null);
        List<LabMemberVo> members=labMemberVos.stream().filter(e -> !e.getUserId().equals(lab.getOwnerId())).collect(Collectors.toList());
        if(owner!=null){
            List<LabMemberVo> rs = new ArrayList<>(labMemberVos.size());
            rs.add(owner);
            rs.addAll(members);
            labMemberVos = rs;
        }
        return labMemberVos;
    }

    @Override
    public List<LabMemberVo> selectBaseVoList(List<Long> labMemberIds) {
        if(labMemberIds!=null && labMemberIds.size()>0){
            return labMemberMapper.selectBaseVoList(labMemberIds);
        }
        return new ArrayList<>(0);
    }

    @Override
    public List<LabMember> getAllByLabId(Long labId) {
        LambdaQueryWrapper<LabMember> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(LabMember::getLabId,labId);
        List<LabMember> labMembers=labMemberMapper.selectList(wrapper);
        if(labMembers!=null && labMembers.size()>0){
            labMembers.forEach(labMember -> {
                labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
            });
        }
        return labMembers;
    }

    @Override
    public Integer selectCount(Long labId,Integer state) {
        return labMemberMapper.selectCount(
                new LambdaQueryWrapper<LabMember>()
                        .eq(LabMember::getLabId,labId)
                        .eq(LabMember::getState,state));
    }

    @Override
    public List<LabMemberSelector> selectLabMemberSelectorList(Long labId,Integer state) {
        return labMemberMapper.selectIdAndNameByState(labId,state);
    }

    @Override
    public LabMember selectByIdAndState(Long labMemberId,Integer state) {
        Assert.isTrue(labMemberId != null && state != null,"参数缺失！");
        LabMember labMember=labMemberMapper.selectOne(
                new LambdaQueryWrapper<LabMember>()
                        .eq(LabMember::getId,labMemberId)
                        .eq(LabMember::getState,state));
        if(labMember!=null){
            labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
        }
        return labMember;
    }

    @Override
    public List<LabMember> selectList(List<Long> memberIds) {
    	List<LabMember> labMembers= new ArrayList<LabMember>();
    	if(CollectionUtils.isNotEmpty(memberIds)) {
    		labMembers=labMemberMapper.selectPoListByIds(memberIds);
    	}
        if(labMembers!=null && labMembers.size()>0){
            labMembers.forEach(labMember -> {
                labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
            });
        }
        return labMembers;
    }


    public List<LabMemberVo> selectByPower(Long labId,String power) {
        List<LabMemberVo> labMemberVos=labMemberMapper.selectByPower(labId,power);
        if(labMemberVos!=null && labMemberVos.size()>0){
            labMemberVos.forEach(labMember -> labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI"));
        }
        return labMemberVos;
    }


    @Override
    public boolean isOwner(Long labId,Long labMemberId) {
        Lab lab=labMapper.selectById(labId);
        LabMember labMember=labMemberMapper.selectById(labMemberId);
        if(lab == null || labMember == null){
            return false;
        }
        return lab.getOwnerId() != null && lab.getOwnerId().equals(labMember.getUserId());
    }
    
    @Override
    public LabMember getOwner(Long labId) {
        Lab lab=labMapper.selectById(labId);
        LabMember labMember= this.selectMember(labId, lab.getOwnerId());
        if(labMember!=null){
            labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
        }
        return labMember;
    }

    @Override
    public LabMemberVo selectMemberVo(Long labMemberId) {
        LabMemberVo labMemberVo=labMemberMapper.selectVo(labMemberId);
        if(labMemberVo!=null){
            LabUserCard myCard = labUserCardService.selectListByLabIdAndUserId(labMemberVo.getLabId(),labMemberVo.getUserId());
            List<LabMemberPower> myPower = labMemberPowerService.selectListByLabIdAndLabMemberId(labMemberVo.getLabId(),labMemberVo.getLabMemberId());
            labMemberVo.setBindCard(myCard!=null ? BoolEnum.TRUE.getValue() : BoolEnum.FALSE.getValue());
            labMemberVo.setPowerList(myPower);
            labMemberVo.setDuty(labMemberVo.getDuty()!=null?labMemberVo.getDuty():"PI");
        }
        return labMemberVo;
    }

   /* @Override
    public List<LabMemberInfo> selectLabMemberByLabid(Long labid){
        return labMemberMapper.selectLabMemberByLabid(labid);
    }*/

    @Override
    public LabMember selectMemberAllState(Long labId,Long userId) {
        LambdaQueryWrapper<LabMember> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(LabMember::getLabId,labId);
        wrapper.eq(LabMember::getUserId,userId);
        LabMember labMember=labMemberMapper.selectOne(wrapper);
        if(labMember!=null){
            labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
        }
        return labMember;
    }

    @Override
    public List<LabMember> selectPoList(Long labId,Integer state) {
        List<LabMember> labMembers=labMemberMapper.selectPoList(labId,state);
        if(labMembers!=null && labMembers.size()>0){
            labMembers.forEach(labMember -> {
                labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
            });
        }
        return labMembers;
    }

    @Override
    public List<LabMemberVo> searchLabMember(String name,Long labId) {
        List<LabMemberVo> labMemberVos=labMemberMapper.searchLabMember(name,labId);
        if(labMemberVos!=null && labMemberVos.size()>0){
            labMemberVos.forEach(labMember -> labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI"));
        }
        return labMemberVos;
    }

    @Override
    public List<LabMember> getTopLastJoinLabList(Integer top, Long labId) {
        return labMemberMapper.getTopLastJoinLabList(top,labId);
    }

    @Override
    public List<LabMember> getLastJoinLabList(Long labId) {
        return labMemberMapper.getLastJoinLabList(labId);
    }

    @Override
    public LabMember selectByLabIdAndUserId(Long labId,Long userId) {
        return labMemberMapper.selectOne(
                new LambdaQueryWrapper<LabMember>()
                        .eq(LabMember::getLabId,labId)
                        .eq(LabMember::getUserId,userId)
                        .eq(LabMember::getState,LabMemberEnum.State.STATE_IN.getValue()));
    }

    @Override
    public List<LabMember> selectAllByUserId(Long userId) {
        List<LabMember> labMembers=labMemberMapper.selectList(
                new LambdaQueryWrapper<LabMember>()
                        .eq(LabMember::getUserId,userId));
        if(labMembers!=null && labMembers.size()>0){
            labMembers.forEach(labMember -> {
                labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
            });
        }
        return labMembers;
    }

    @Override
    public List<LabMember> selectListByUserId(Long userId) {
        List<LabMember> labMembers=labMemberMapper.selectList(
                new LambdaQueryWrapper<LabMember>()
                        .eq(LabMember::getUserId,userId)
                        .eq(LabMember::getState,LabMemberEnum.State.STATE_IN.getValue()));
        if(labMembers!=null && labMembers.size()>0){
            labMembers.forEach(labMember -> {
                labMember.setDuty(labMember.getDuty()!=null?labMember.getDuty():"PI");
            });
        }
        return labMembers;
    }

	@Override
	public List<UsersVo> selectMemberByPower(Long labId, List<String> powerList) {
		return labMemberMapper.selectMemberByPower(labId, powerList);
	}
	
	@Override
	public List<MemberInfoVo> selectMemberVoList(Long labId, Integer state){
		return labMemberMapper.selectMemberVoList(labId, state);
	}
    
	@Override
	public List<MemberInfoVo> selectMemberVoListByIds(List<Long> labMemberIds){
		return labMemberMapper.selectMemberVoListByIds(labMemberIds);
    }

	@Override
	public List<Long> selectMemberIds(Long labId, Integer state) {
		return labMemberMapper.selectMemberIds(labId, state);
	}

    @Override
    public LabMember insert(LabMember labMember) {
        labMemberMapper.insert(labMember);
        return labMember;
    }

	@Override
	public List<LabMember> selectListByIds(List<Long> memberIds) {
		LambdaQueryWrapper<LabMember> wrapper=new LambdaQueryWrapper<>();
        wrapper.in(LabMember::getId,memberIds);
        wrapper.eq(LabMember::getState,LabMemberEnum.State.STATE_IN.getValue());
        return labMemberMapper.selectList(wrapper);
	}
}
